﻿namespace Pub.Class
{
    using System;
    using System.Collections.Generic;
    using System.Reflection;
    using System.Threading;

    public class SafeListSlim<V>
    {
        private readonly List<V> cache;
        private readonly ReaderWriterLockSlim cacheLock;

        public SafeListSlim()
        {
            this.cache = new List<V>();
            this.cacheLock = new ReaderWriterLockSlim();
        }

        public SafeListSlim<V> Add(V value)
        {
            this.cacheLock.EnterWriteLock();
            try
            {
                this.cache.Add(value);
            }
            finally
            {
                this.cacheLock.ExitWriteLock();
            }
            return (SafeListSlim<V>) this;
        }

        public SafeListSlim<V> AddUnique(V value)
        {
            if (this.Contains(value))
            {
                return (SafeListSlim<V>) this;
            }
            return this.Add(value);
        }

        public SafeListSlim<V> Clear()
        {
            this.cacheLock.EnterWriteLock();
            try
            {
                this.cache.Clear();
            }
            finally
            {
                this.cacheLock.ExitWriteLock();
            }
            return (SafeListSlim<V>) this;
        }

        public bool Contains(V value)
        {
            return (this.IndexOf(value) >= 0);
        }

        public int IndexOf(V value)
        {
            int index;
            this.cacheLock.EnterReadLock();
            try
            {
                index = this.cache.IndexOf(value);
            }
            finally
            {
                this.cacheLock.ExitReadLock();
            }
            return index;
        }

        public SafeListSlim<V> Insert(int index, V value)
        {
            this.cacheLock.EnterWriteLock();
            try
            {
                this.cache.Insert(index, value);
            }
            finally
            {
                this.cacheLock.ExitWriteLock();
            }
            return (SafeListSlim<V>) this;
        }

        public SafeListSlim<V> InsertUnique(int index, V value)
        {
            if (this.Contains(value))
            {
                return (SafeListSlim<V>) this;
            }
            return this.Insert(index, value);
        }

        public int LastIndexOf(V value)
        {
            int num;
            this.cacheLock.EnterReadLock();
            try
            {
                num = this.cache.LastIndexOf(value);
            }
            finally
            {
                this.cacheLock.ExitReadLock();
            }
            return num;
        }

        public V Pop()
        {
            if (this.cache.Count == 0)
            {
                return default(V);
            }
            V local = this.cache[0];
            this.Remove(0);
            return local;
        }

        public SafeListSlim<V> Push(V value)
        {
            return this.Add(value);
        }

        public SafeListSlim<V> Remove(int index)
        {
            this.cacheLock.EnterWriteLock();
            try
            {
                this.cache.RemoveAt(index);
            }
            finally
            {
                this.cacheLock.ExitWriteLock();
            }
            return (SafeListSlim<V>) this;
        }

        public bool Remove(V value)
        {
            bool flag;
            this.cacheLock.EnterWriteLock();
            try
            {
                flag = this.cache.Remove(value);
            }
            finally
            {
                this.cacheLock.ExitWriteLock();
            }
            return flag;
        }

        public SafeListSlim<V> Reverse()
        {
            this.cacheLock.EnterWriteLock();
            try
            {
                this.cache.Reverse();
            }
            finally
            {
                this.cacheLock.ExitWriteLock();
            }
            return (SafeListSlim<V>) this;
        }

        public int Count
        {
            get
            {
                int count;
                this.cacheLock.EnterReadLock();
                try
                {
                    count = this.cache.Count;
                }
                finally
                {
                    this.cacheLock.ExitReadLock();
                }
                return count;
            }
        }

        public V this[int index]
        {
            get
            {
                V local;
                this.cacheLock.EnterReadLock();
                try
                {
                    local = this.cache[index];
                }
                finally
                {
                    this.cacheLock.ExitReadLock();
                }
                return local;
            }
            set
            {
                this.cacheLock.EnterWriteLock();
                try
                {
                    this.cache[index] = value;
                }
                finally
                {
                    this.cacheLock.ExitWriteLock();
                }
            }
        }
    }
}

